#ifndef MDTX_USE_RCPPARMADILLO
#define MDTX_USE_RCPPARMADILLO
#endif

#include <RcppArmadillo.h>
using namespace Rcpp;

#include <vector>
#include "mdtx-online/utility/lis.h"

class lis_size_c
{
private:
    std::vector<int> top;

public:
    lis_size_c()
    {
    }

    int run(NumericVector x)
    {
        R_xlen_t n = x.length();
        top.reserve(n);
        return lis_size(x, n, top);
    }
};

//' LIS size
//'
//'
//' @param x Numeric vector x
//' @return Integer
//' @export
// [[Rcpp::export]]
int lis_size(NumericVector x)
{
    lis_size_c c{};
    return c.run(x);
}

class lis_index_c
{
private:
    // reused, new IntegerVectors are created when calling Rcpp::wrap
    std::vector<int> idx, parent;

public:
    lis_index_c()
        : idx(),
          parent()
    {
    }

    IntegerVector run(NumericVector x)
    {
        R_xlen_t n = x.length();
        idx.reserve(n);
        parent.reserve(n);
        lis_idx(x, n, idx, parent);
        return wrap(idx);
    }
};

//' LIS index
//'
//' The returned indices are offsets to first element (0 based)
//'
//' @param x Numeric vector x
//' @return Integer vector
//' @export
// [[Rcpp::export]]
IntegerVector lis_index(NumericVector x)
{
    lis_index_c c{};
    return c.run(x);
}

RCPP_MODULE(offline_lis)
{
    Rcpp::class_<lis_size_c>("lis_size_c")
        .constructor()
        .method("run", &lis_size_c::run);

    Rcpp::class_<lis_index_c>("lis_index_c")
        .constructor()
        .method("run", &lis_index_c::run);
}
